package com.sdy.usercenter.biz.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sdy.common.model.BizException;
import com.sdy.common.utils.Assert;
import com.sdy.common.utils.MapUtil;
import com.sdy.usercenter.biz.mapper.SysResourceMapper;
import com.sdy.usercenter.biz.mapper.SysRoleResourceMapper;
import com.sdy.usercenter.biz.model.SysApplication;
import com.sdy.usercenter.biz.mapper.SysApplicationMapper;
import com.sdy.usercenter.biz.model.SysResource;
import com.sdy.usercenter.biz.model.SysRoleResource;
import com.sdy.usercenter.biz.service.SysApplicationService;
import com.sdy.mvc.service.impl.BaseServiceImpl;
import com.sdy.usercenter.biz.service.SysResourceService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author zzq
 * @since 2019-12-12
 */
@Slf4j
@Service
public class SysApplicationServiceImpl extends BaseServiceImpl<SysApplication> implements SysApplicationService {
    @Autowired
    private SysApplicationMapper sysApplicationMapper;
    @Autowired
    private SysResourceMapper sysResourceMapper;
    @Autowired
    private SysResourceService sysResourceService;
    @Autowired
    private SysRoleResourceMapper sysRoleResourceMapper;

    @Override
    public List<SysApplication> appListWithAuth(Integer roleId) {
        List<SysApplication> appList = lambdaQuery().orderByAsc(SysApplication::getId).list();
        if (roleId == null || appList.isEmpty()) {
            return appList;
        }
        List<SysResource> resList = sysResourceMapper.selectList(new LambdaQueryWrapper<SysResource>()
                .in(SysResource::getCode, appList.stream().map(SysApplication::getCode).collect(Collectors.toList())));
        if (!resList.isEmpty()) {
            List<SysRoleResource> roleResList = sysRoleResourceMapper.selectList(new LambdaQueryWrapper<SysRoleResource>()
                    .eq(SysRoleResource::getRoleId, roleId)
                    .in(SysRoleResource::getResourceId, resList.stream().map(SysResource::getId).collect(Collectors.toList())));
            Set<Integer> resIdSet = roleResList.stream().map(SysRoleResource::getResourceId).collect(Collectors.toSet());
            Set<String> authCodeSet = resList.stream().filter(item -> resIdSet.contains(item.getId())).map(SysResource::getCode).collect(Collectors.toSet());
            appList.forEach(app -> {
                app.setAuthed(authCodeSet.contains(app.getCode()));
            });
        }
        return appList;
    }

    @Override
    public void saveApplication(SysApplication sysApplication) throws BizException {
        Assert.isTrue(lambdaQuery().eq(SysApplication::getCode, sysApplication.getCode()).count() > 0, "系统编码重复！");
        SysResource res = sysResourceService.lambdaQuery().eq(SysResource::getCode, sysApplication.getCode()).one();
        if (res == null) {
            res = createRootRes(sysApplication);
        }
        sysApplication.setResId(res.getId());
        save(sysApplication);
    }

    @Override
    public void updateApplication(SysApplication sysApplication) throws BizException {
        Assert.isTrue(lambdaQuery()
                .eq(SysApplication::getCode, sysApplication.getCode())
                .ne(SysApplication::getId, sysApplication.getId())
                .count() > 0, "系统编码重复！");
        SysApplication app = getById(sysApplication.getId());
        SysResource res = sysResourceService.getById(app.getResId());
        if (res == null) {
            createRootRes(sysApplication);
        } else {
            sysResourceService.updateById(new SysResource()
                    .setName(sysApplication.getName())
                    .setCode(sysApplication.getCode())
                    .setUrl(sysApplication.getUrl())
                    .setId(res.getId()));
        }
        updateById(sysApplication);
    }
    
    private SysResource createRootRes(SysApplication application) {
        SysResource res = new SysResource()
                .setAuthentication(1)
                .setAuthorization(1)
                .setUrl(application.getUrl())
                .setType(1)
                .setCode(application.getCode())
                .setParentId(0)
                .setState(1)
                .setCreateTime(new Date())
                .setSort(1)
                .setName(application.getName());
        sysResourceService.save(res);
        sysResourceService.updateById(new SysResource().setId(res.getId()).setRootId(res.getId()));
        return res;
    }

    @Override
    public void deleteApplication(Integer id) {
        SysApplication app = getById(id);
        if (app != null) {
            removeById(id);
            sysResourceService.deleteResource(Collections.singletonList(app.getResId()));
        }
    }
}
